/*
 * Copyright (c) 2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <gtest/gtest.h>

#include <vector>

#include "sec_storage_ipc_stub_serialization.h"
#include "test_helpers.h"

namespace OHOS {
namespace SeBaseServices {
namespace UnitTest {
using namespace testing;

TEST(SecStorageIpcStubSerialTest, SetFactoryResetAuthKeyInputFromBufferNullptrInput)
{
    {
        auto ret = SetFactoryResetAuthKeyInputFromBuffer(nullptr, nullptr, nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        SharedDataBuffer buffer {};
        auto ret = SetFactoryResetAuthKeyInputFromBuffer(&buffer, nullptr, nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        SharedDataBuffer buffer {};
        FactoryResetLevel level = LEVEL_USER_WIPE;

        auto ret = SetFactoryResetAuthKeyInputFromBuffer(&buffer, &level, nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        SharedDataBuffer buffer {};
        FactoryResetLevel level = LEVEL_USER_WIPE;
        FactoryResetAuthAlgo algo = ALGO_NIST_P256;
        auto ret = SetFactoryResetAuthKeyInputFromBuffer(&buffer, &level, &algo, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
}

TEST(SecStorageIpcStubSerialTest, SetFactoryResetAuthKeyInputFromBufferSuccess)
{
    std::string inputStr = "02000000"                                                          // LEVEL_ALL_WIPE = 2
                           "01000000"                                                          // ALGO_SM2 = 1
                           "20000000"                                                          // keySize = 32
                           "ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB"; // 32 ab s
    auto input = TestHelpers::HexStringToVector(inputStr);

    SharedDataBuffer buffer {.data = input.data(), .dataSize = static_cast<uint32_t>(input.size()), .dataMaxSize = 512};
    FactoryResetLevel level = LEVEL_USER_WIPE;
    FactoryResetAuthAlgo algo = ALGO_NIST_P256;

    uint32_t keySize = 128;
    uint8_t keyData[128] = {0};
    StorageAuthKey key = {.keyData = keyData, .keySize = keySize};
    auto ret = SetFactoryResetAuthKeyInputFromBuffer(&buffer, &level, &algo, &key);
    EXPECT_EQ(ret, SUCCESS);
    EXPECT_EQ(level, LEVEL_ALL_WIPE);
    EXPECT_EQ(algo, ALGO_SM2);
    EXPECT_EQ(key.keySize, 32);

    EXPECT_EQ(TestHelpers::VectorToHexString(key.keyData, key.keySize),
        "ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB");
}

TEST(SecStorageIpcStubSerialTest, SetFactoryResetAuthKeyInputFromBufferCaseDeserializeError)
{
    auto process = [](const std::string &inputStr) -> ResultCode {
        auto input = TestHelpers::HexStringToVector(inputStr);

        SharedDataBuffer buffer {
            .data = input.data(),
            .dataSize = static_cast<uint32_t>(input.size()),
            .dataMaxSize = static_cast<uint32_t>(input.size()),
        };
        FactoryResetLevel level = LEVEL_USER_WIPE;
        FactoryResetAuthAlgo algo = ALGO_NIST_P256;

        uint32_t keySize = 128;
        uint8_t keyData[128] = {0};
        StorageAuthKey key = {.keyData = keyData, .keySize = keySize};
        return SetFactoryResetAuthKeyInputFromBuffer(&buffer, &level, &algo, &key);
    };

    {
        std::string inputStr = "02000"; // not enough at 1st para
        EXPECT_EQ(process(inputStr), IPC_PARA_PROCESS_ERR_INDEX_1);
    }
    {
        std::string inputStr = "02000000" // LEVEL_ALL_WIPE = 2
                               "01000";   // not enough at 2nd para
        EXPECT_EQ(process(inputStr), IPC_PARA_PROCESS_ERR_INDEX_2);
    }
    {
        std::string inputStr = "02000000" // LEVEL_ALL_WIPE = 2
                               "01000000" // ALGO_SM2 = 1
                               "20000";   // not enough at 3rd para
        EXPECT_EQ(process(inputStr), IPC_PARA_PROCESS_ERR_INDEX_3);
    }

    {
        std::string inputStr = "02000000"        // LEVEL_ALL_WIPE = 2
                               "01000000"        // ALGO_SM2 = 1
                               "20000000"        // keySize = 32
                               "ABABABABABABAB"; // not enough at 4th para
        EXPECT_EQ(process(inputStr), IPC_PARA_PROCESS_ERR_INDEX_4);
    }
}

TEST(SecStorageIpcStubSerialTest, GetFactoryResetAuthKeyAlgoInputFromBufferCaseNullptr)
{
    {
        auto result = GetFactoryResetAuthKeyAlgoInputFromBuffer(nullptr, nullptr);
        EXPECT_EQ(result, INVALID_PARA_NULL_PTR);
    }
    {
        SharedDataBuffer buffer {};
        auto result = GetFactoryResetAuthKeyAlgoInputFromBuffer(&buffer, nullptr);
        EXPECT_EQ(result, INVALID_PARA_NULL_PTR);
    }
}

TEST(SecStorageIpcStubSerialTest, GetFactoryResetAuthKeyAlgoInputFromBufferCaseSizeNotRight)
{
    uint8_t data[] = {1, 2, 3, 4, 5, 6, 7, 8};
    SharedDataBuffer buffer {.data = data, .dataSize = sizeof(data), .dataMaxSize = sizeof(data)};

    FactoryResetLevel level = LEVEL_ALL_WIPE;
    auto result = GetFactoryResetAuthKeyAlgoInputFromBuffer(&buffer, &level);
    EXPECT_EQ(result, INVALID_PARA_ERR_SIZE);
    EXPECT_EQ(level, LEVEL_ALL_WIPE);
}

TEST(SecStorageIpcStubSerialTest, GetFactoryResetAuthKeyAlgoInputFromBufferCaseSuccess)
{
    uint8_t data[] = {1, 2, 3, 4};
    SharedDataBuffer buffer {.data = data, .dataSize = sizeof(data), .dataMaxSize = sizeof(data)};

    FactoryResetLevel level = LEVEL_ALL_WIPE;
    auto result = GetFactoryResetAuthKeyAlgoInputFromBuffer(&buffer, &level);
    EXPECT_EQ(result, SUCCESS);
    EXPECT_EQ((uint32_t)level, 0x04030201);
}

TEST(SecStorageIpcStubSerialTest, GetFactoryResetAuthKeyAlgoOutputToBufferCaseNullptr)
{
    auto result = GetFactoryResetAuthKeyAlgoOutputToBuffer(ALGO_NIST_P256, nullptr);
    EXPECT_EQ(result, INVALID_PARA_NULL_PTR);
}

TEST(SecStorageIpcStubSerialTest, GetFactoryResetAuthKeyAlgoOutputToBufferCaseNotRightSize)
{
    uint8_t data[] = {1, 2};
    SharedDataBuffer buffer {.data = data, .dataSize = sizeof(data), .dataMaxSize = sizeof(data)};

    auto result = GetFactoryResetAuthKeyAlgoOutputToBuffer(ALGO_NIST_P256, &buffer);
    EXPECT_EQ(result, INVALID_PARA_ERR_SIZE);
}

TEST(SecStorageIpcStubSerialTest, GetFactoryResetAuthKeyAlgoOutputToBufferCaseSuccess)
{
    uint8_t data[] = {0xFF, 0xFF, 0xFF, 0xFF};
    SharedDataBuffer buffer {.data = data, .dataSize = sizeof(data), .dataMaxSize = sizeof(data)};

    auto result = GetFactoryResetAuthKeyAlgoOutputToBuffer(ALGO_SM2, &buffer);
    EXPECT_EQ(result, SUCCESS);
    // data will be set as 0x01000000
    EXPECT_EQ(data[0], 1);
    EXPECT_EQ(data[1], 0);
    EXPECT_EQ(data[2], 0);
    EXPECT_EQ(data[3], 0);
}

TEST(SecStorageIpcStubSerialTest, PrepareFactoryResetOutputToBufferCaseNullInput)
{
    {
        auto ret = PrepareFactoryResetOutputToBuffer(nullptr, 0, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }

    {
        uint8_t keyData[128] = {0};
        auto ret = PrepareFactoryResetOutputToBuffer(keyData, 0, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }

    {
        uint32_t keySize = 128;
        uint8_t keyData[128] = {0};
        auto ret = PrepareFactoryResetOutputToBuffer(keyData, keySize, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
}

TEST(SecStorageIpcStubSerialTest, PrepareFactoryResetOutputToBufferCaseSuccess)
{
    std::vector<uint8_t> nonce(64, 0xab);

    uint8_t data[256] = {0};
    uint32_t size = sizeof(data);
    SharedDataBuffer buff = {data, size, size};

    auto ret = PrepareFactoryResetOutputToBuffer(nonce.data(), static_cast<uint32_t>(nonce.size()), &buff);
    EXPECT_EQ(ret, SUCCESS);
    EXPECT_EQ(buff.dataSize, 68);

    std::string expect = "40000000"                         // size = 64
                         "ABABABABABABABABABABABABABABABAB" // 64 ab
                         "ABABABABABABABABABABABABABABABAB"
                         "ABABABABABABABABABABABABABABABAB"
                         "ABABABABABABABABABABABABABABABAB";

    EXPECT_EQ(TestHelpers::VectorToHexString(buff.data, buff.dataSize), expect);
}

TEST(SecStorageIpcStubSerialTest, PrepareFactoryResetOutputToBufferSerializeError)
{
    auto process = [](uint32_t size) -> ResultCode {
        std::vector<uint8_t> nonce(64, 0xab);

        std::unique_ptr<uint8_t[]> data = std::make_unique<uint8_t[]>(size);

        SharedDataBuffer buff = {data.get(), size, size};

        return PrepareFactoryResetOutputToBuffer(nonce.data(), static_cast<uint32_t>(nonce.size()), &buff);
    };

    EXPECT_EQ(process(sizeof(uint32_t) - 1), IPC_PARA_PROCESS_ERR_INDEX_1);
    EXPECT_EQ(process(sizeof(uint32_t) + 1), IPC_PARA_PROCESS_ERR_INDEX_2);
}

TEST(SecStorageIpcStubSerialTest, ProcessFactoryResetInputFromBufferCaseNullInput)
{
    {
        auto ret = ProcessFactoryResetInputFromBuffer(nullptr, nullptr, nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        SharedDataBuffer buffer {};
        auto ret = ProcessFactoryResetInputFromBuffer(&buffer, nullptr, nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        SharedDataBuffer buffer {};
        FactoryResetLevel level = LEVEL_USER_WIPE;
        auto ret = ProcessFactoryResetInputFromBuffer(&buffer, &level, nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }

    {
        SharedDataBuffer buffer {};
        FactoryResetLevel level = LEVEL_USER_WIPE;
        uint8_t cred[128] = {0};
        auto ret = ProcessFactoryResetInputFromBuffer(&buffer, &level, cred, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
}

TEST(SecStorageIpcStubSerialTest, ProcessFactoryResetInputFromBufferCaseSuccess)
{
    auto process = [](const std::string &inputStr) -> ResultCode {
        auto input = TestHelpers::HexStringToVector(inputStr);

        SharedDataBuffer buffer {.data = input.data(),
            .dataSize = static_cast<uint32_t>(input.size()),
            .dataMaxSize = 512};

        FactoryResetLevel level = LEVEL_USER_WIPE;
        uint8_t cred[32] = {0};
        uint32_t size = 32;
        return ProcessFactoryResetInputFromBuffer(&buffer, &level, cred, &size);
    };

    {
        std::string inputStr = "020"; // not enough at 1st para
        EXPECT_EQ(process(inputStr), IPC_PARA_PROCESS_ERR_INDEX_1);
    }

    {
        std::string inputStr = "02000000" // LEVEL_ALL_WIPE = 2
                               "200";     // not enough at 2st para
        EXPECT_EQ(process(inputStr), IPC_PARA_PROCESS_ERR_INDEX_2);
    }

    {
        std::string inputStr = "02000000"  // LEVEL_ALL_WIPE = 2
                               "21000000"; // the 2st para is too big
        EXPECT_EQ(process(inputStr), IPC_PARA_PROCESS_ERR_INVALID_VALUE);
    }
    {
        std::string inputStr = "02000000" // LEVEL_ALL_WIPE = 2
                               "21000000" // keySize = 33
                               "ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB"; // 33 abs
        EXPECT_EQ(process(inputStr), IPC_PARA_PROCESS_ERR_INVALID_VALUE);
    }
}

TEST(SecStorageIpcStubSerialTest, ProcessFactoryResetInputFromBufferCaseDeserializeError)
{
    std::string inputStr = "02000000"                                                          // LEVEL_ALL_WIPE = 2
                           "20000000"                                                          // keySize = 32
                           "ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB"; // 32 abs

    auto input = TestHelpers::HexStringToVector(inputStr);

    SharedDataBuffer buffer {.data = input.data(), .dataSize = static_cast<uint32_t>(input.size()), .dataMaxSize = 512};

    FactoryResetLevel level = LEVEL_USER_WIPE;
    uint8_t cred[128] = {0};
    uint32_t size = 128;
    auto ret = ProcessFactoryResetInputFromBuffer(&buffer, &level, cred, &size);
    EXPECT_EQ(ret, SUCCESS);
    EXPECT_EQ(level, LEVEL_ALL_WIPE);
    EXPECT_EQ(size, 0x20);
    EXPECT_EQ(TestHelpers::VectorToHexString(cred, size),
        "ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB");
}

TEST(SecStorageIpcStubSerialTest, SetToUserModeInputFromBufferCaseNullInput)
{
    {
        auto ret = SetToUserModeInputFromBuffer(nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        SharedDataBuffer buffer {};
        auto ret = SetToUserModeInputFromBuffer(&buffer, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
}

TEST(SecStorageIpcStubSerialTest, SetToUserModeInputFromBufferCaseInvaliedSize)
{
    std::string inputStr = "CDAB3412" // 0x1234abcd
                           "21437856" // 0x56784321
                           "??";      // size is not right
    auto input = TestHelpers::HexStringToVector(inputStr);

    SharedDataBuffer buffer {.data = input.data(), .dataSize = static_cast<uint32_t>(input.size()), .dataMaxSize = 512};

    StorageUserModeConf conf = {0, 0};
    auto ret = SetToUserModeInputFromBuffer(&buffer, &conf);
    EXPECT_EQ(ret, INVALID_PARA_ERR_SIZE);
}

TEST(SecStorageIpcStubSerialTest, SetToUserModeInputFromBufferCaseSuccess)
{
    std::string inputStr = "CDAB3412"  // 0x1234abcd
                           "21437856"; // 0x56784321
    auto input = TestHelpers::HexStringToVector(inputStr);

    SharedDataBuffer buffer {.data = input.data(), .dataSize = static_cast<uint32_t>(input.size()), .dataMaxSize = 512};

    StorageUserModeConf conf = {0, 0};
    auto ret = SetToUserModeInputFromBuffer(&buffer, &conf);
    EXPECT_EQ(ret, SUCCESS);
    EXPECT_EQ(conf.pkResetable, 0x1234abcd);
    EXPECT_EQ(conf.slotsResetable, 0x56784321);
}

TEST(SecStorageIpcStubSerialTest, GetSlotOperateAlgorithmInputFromBufferCaseNullptr)
{
    {
        auto ret = GetSlotOperateAlgorithmInputFromBuffer(nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        SharedDataBuffer buffer {};
        auto ret = GetSlotOperateAlgorithmInputFromBuffer(&buffer, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
}

TEST(SecStorageIpcStubSerialTest, GetSlotOperateAlgorithmInputFromBufferCaseInputSizeError)
{
    std::string inputStr = "CDAB3412"  // 0x1234abcd
                           "21437856"; // 0x56784321
    auto input = TestHelpers::HexStringToVector(inputStr);

    SharedDataBuffer buffer {
        .data = input.data(),
        .dataSize = static_cast<uint32_t>(input.size()),
        .dataMaxSize = static_cast<uint32_t>(input.size()),
    };
    SlotOperAlgo algo = ALGO_HKDF_SHA256;
    auto ret = GetSlotOperateAlgorithmInputFromBuffer(&buffer, &algo);
    EXPECT_EQ(ret, INVALID_PARA_ERR_SIZE);
}

TEST(SecStorageIpcStubSerialTest, GetSlotOperateAlgorithmInputFromBufferCaseInputSuccess)
{
    std::string inputStr = "CDAB3412"; // 0x1234abcd

    auto input = TestHelpers::HexStringToVector(inputStr);

    SharedDataBuffer buffer {
        .data = input.data(),
        .dataSize = static_cast<uint32_t>(input.size()),
        .dataMaxSize = static_cast<uint32_t>(input.size()),
    };
    SlotOperAlgo algo = ALGO_HKDF_SHA256;
    auto ret = GetSlotOperateAlgorithmInputFromBuffer(&buffer, &algo);
    EXPECT_EQ(ret, SUCCESS);
    EXPECT_EQ(algo, 0x1234abcd);
}

TEST(SecStorageIpcStubSerialTest, GetSlotOperateAlgorithmOutputToBufferNullptr)
{
    auto ret = GetSlotOperateAlgorithmOutputToBuffer(1, nullptr);
    EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
}

TEST(SecStorageIpcStubSerialTest, GetSlotOperateAlgorithmOutputToBufferIsNotEnough)
{
    uint8_t data = 0;

    SharedDataBuffer buffer {
        .data = &data,
        .dataSize = sizeof(data),
        .dataMaxSize = sizeof(data),
    };

    auto ret = GetSlotOperateAlgorithmOutputToBuffer(1, &buffer);
    EXPECT_EQ(ret, INVALID_PARA_ERR_SIZE);
}

TEST(SecStorageIpcStubSerialTest, GetSlotOperateAlgorithmOutputToBufferSuccess)
{
    uint32_t data = 0;

    SharedDataBuffer buffer {
        .data = (uint8_t *)&data,
        .dataSize = sizeof(data),
        .dataMaxSize = sizeof(data),
    };

    auto ret = GetSlotOperateAlgorithmOutputToBuffer(0x12345678, &buffer);
    EXPECT_EQ(ret, SUCCESS);
    EXPECT_EQ(data, 0x12345678);
}

TEST(SecStorageIpcStubSerialTest, GetFactoryResetAlgorithmInputFromBufferCaseNullptr)
{
    {
        auto ret = GetFactoryResetAlgorithmInputFromBuffer(nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        SharedDataBuffer buffer {};
        auto ret = GetFactoryResetAlgorithmInputFromBuffer(&buffer, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
}

TEST(SecStorageIpcStubSerialTest, GetFactoryResetAlgorithmInputFromBufferCaseInputSizeError)
{
    std::string inputStr = "CDAB3412"  // 0x1234abcd
                           "21437856"; // 0x56784321
    auto input = TestHelpers::HexStringToVector(inputStr);

    SharedDataBuffer buffer {
        .data = input.data(),
        .dataSize = static_cast<uint32_t>(input.size()),
        .dataMaxSize = static_cast<uint32_t>(input.size()),
    };
    FactoryResetAuthAlgo algo = ALGO_NIST_P256;
    auto ret = GetFactoryResetAlgorithmInputFromBuffer(&buffer, &algo);
    EXPECT_EQ(ret, INVALID_PARA_ERR_SIZE);
}

TEST(SecStorageIpcStubSerialTest, GetFactoryResetAlgorithmInputFromBufferCaseInputSuccess)
{
    std::string inputStr = "CDAB3412"; // 0x1234abcd

    auto input = TestHelpers::HexStringToVector(inputStr);

    SharedDataBuffer buffer {
        .data = input.data(),
        .dataSize = static_cast<uint32_t>(input.size()),
        .dataMaxSize = static_cast<uint32_t>(input.size()),
    };
    FactoryResetAuthAlgo algo = ALGO_NIST_P256;
    auto ret = GetFactoryResetAlgorithmInputFromBuffer(&buffer, &algo);
    EXPECT_EQ(ret, SUCCESS);
    EXPECT_EQ(algo, 0x1234abcd);
}

TEST(SecStorageIpcStubSerialTest, GetFactoryResetAlgorithmOutputToBufferCaseNullptrInput)
{
    auto ret = GetFactoryResetAlgorithmOutputToBuffer(1, nullptr);
    EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
}

TEST(SecStorageIpcStubSerialTest, GetFactoryResetAlgorithmOutputToBufferCaseBufferIsNotEnough)
{
    uint8_t data = 0;

    SharedDataBuffer buffer {
        .data = &data,
        .dataSize = sizeof(data),
        .dataMaxSize = sizeof(data),
    };

    auto ret = GetFactoryResetAlgorithmOutputToBuffer(1, &buffer);
    EXPECT_EQ(ret, INVALID_PARA_ERR_SIZE);
}

TEST(SecStorageIpcStubSerialTest, GetFactoryResetAlgorithmOutputToBufferCaseSuccess)
{
    uint32_t data = 0;

    SharedDataBuffer buffer {
        .data = (uint8_t *)&data,
        .dataSize = sizeof(data),
        .dataMaxSize = sizeof(data),
    };

    auto ret = GetFactoryResetAlgorithmOutputToBuffer(0x11223344, &buffer);
    EXPECT_EQ(ret, SUCCESS);
    EXPECT_EQ(data, 0x11223344);
}

TEST(SecStorageIpcStubSerialTest, SetSetAllSlotsSizeInputFromBufferCaseNullptr)
{
    {
        auto ret = SetSetAllSlotsSizeInputFromBuffer(nullptr, nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        SharedDataBuffer buffer;
        auto ret = SetSetAllSlotsSizeInputFromBuffer(&buffer, nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        SharedDataBuffer buffer;
        uint16_t array[128] = {0};
        auto ret = SetSetAllSlotsSizeInputFromBuffer(&buffer, array, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
}

TEST(SecStorageIpcStubSerialTest, SetSetAllSlotsSizeInputFromBufferCaseSuccess)
{
    std::string inputStr = "06000000" // size = 6
                           "AABB"     // data = {0xbbaa, 0xddcc, 0xffee, 0xdddd, 0xeeee, 0xffff};
                           "CCDD"
                           "EEFF"
                           "DDDD"
                           "EEEE"
                           "FFFF";
    auto input = TestHelpers::HexStringToVector(inputStr);

    SharedDataBuffer buffer {
        .data = input.data(),
        .dataSize = static_cast<uint32_t>(input.size()),
        .dataMaxSize = static_cast<uint32_t>(input.size()),
    };

    uint16_t array[128] = {0};
    uint32_t size = 128;
    auto ret = SetSetAllSlotsSizeInputFromBuffer(&buffer, array, &size);
    EXPECT_EQ(ret, SUCCESS);
    EXPECT_EQ(size, 6);
    EXPECT_EQ(array[0], 0xbbaa);
    EXPECT_EQ(array[1], 0xddcc);
    EXPECT_EQ(array[2], 0xffee);
    EXPECT_EQ(array[3], 0xdddd);
    EXPECT_EQ(array[4], 0xeeee);
    EXPECT_EQ(array[5], 0xffff);
    EXPECT_EQ(array[6], 0);
}

TEST(SecStorageIpcStubSerialTest, SetSetAllSlotsSizeInputFromBufferCaseInvaliedInputSize)
{
    auto process = [](std::string &inputStr) -> ResultCode {
        auto input = TestHelpers::HexStringToVector(inputStr);

        SharedDataBuffer buffer {
            .data = input.data(),
            .dataSize = static_cast<uint32_t>(input.size()),
            .dataMaxSize = static_cast<uint32_t>(input.size()),
        };

        uint16_t array[6] = {0};
        uint32_t size = 6;
        return SetSetAllSlotsSizeInputFromBuffer(&buffer, array, &size);
    };

    {
        std::string inputStr = "0600"; // size is not enough
        EXPECT_EQ(process(inputStr), IPC_PARA_PROCESS_ERR_INDEX_1);
    }

    {
        std::string inputStr = "FF000000" // size is too big (bigger than 80)
                               "AABB"     // data = {0xbbaa, 0xddcc, 0xffee, 0xdddd, 0xeeee, 0xffff};
                               "CCDD"
                               "EEFF"
                               "DDDD"
                               "EEEE"
                               "FFFF";
        EXPECT_EQ(process(inputStr), IPC_PARA_PROCESS_ERR_INVALID_VALUE);
    }
    {
        std::string inputStr = "15000000" // size is too big (not bigger than 80, but bigger than input array size = 6)
                               "AABB"     // data = {0xbbaa, 0xddcc, 0xffee, 0xdddd, 0xeeee, 0xffff};
                               "CCDD"
                               "EEFF"
                               "DDDD"
                               "EEEE"
                               "FFFF";
        EXPECT_EQ(process(inputStr), IPC_PARA_PROCESS_ERR_INVALID_VALUE);
    }
    {
        std::string inputStr = "07000000" // size = 7, bigger than input array size = 6
                               "AABB"     // data = {0xbbaa, 0xddcc, 0xffee, 0xdddd, 0xeeee, 0xffff};
                               "CCDD"
                               "EEFF"
                               "DDDD"
                               "EEEE"
                               "FFFF"
                               "AAAA";
        EXPECT_EQ(process(inputStr), IPC_PARA_PROCESS_ERR_INVALID_VALUE);
    }
}

TEST(SecStorageIpcStubSerialTest, GetAllSlotsSizeOutputToBufferCaseNullptr)
{
    {
        auto ret = GetAllSlotsSizeOutputToBuffer(nullptr, 0, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        uint16_t array[128] = {0};
        auto ret = GetAllSlotsSizeOutputToBuffer(array, 0, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        uint16_t array[128] = {0};
        auto ret = GetAllSlotsSizeOutputToBuffer(array, 128, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        uint16_t array[16] = {0};
        auto ret = GetAllSlotsSizeOutputToBuffer(array, 16, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
}

TEST(SecStorageIpcStubSerialTest, GetAllSlotsSizeOutputToBufferCaseSuccess)
{
    uint8_t data[128] = {0};
    SharedDataBuffer buffer = {
        .data = data,
        .dataSize = sizeof(data),
        .dataMaxSize = sizeof(data),
    };

    uint16_t array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    auto ret = GetAllSlotsSizeOutputToBuffer(array, sizeof(array) / sizeof(uint16_t), &buffer);
    EXPECT_EQ(ret, SUCCESS);

    std::string outString = "0A000000" // 10
                            "0100"
                            "0200"
                            "0300"
                            "0400"
                            "0500"
                            "0600"
                            "0700"
                            "0800"
                            "0900"
                            "0A00";
    EXPECT_EQ(outString, TestHelpers::VectorToHexString(buffer.data, buffer.dataSize));
}

TEST(SecStorageIpcStubSerialTest, GetAllSlotsSizeOutputToBufferCaseOutBufferIsNotEnough)
{
    uint8_t data[4] = {0}; // very small
    SharedDataBuffer buffer = {
        .data = data,
        .dataSize = sizeof(data),
        .dataMaxSize = sizeof(data),
    };

    uint16_t array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    auto ret = GetAllSlotsSizeOutputToBuffer(array, sizeof(array) / sizeof(uint16_t), &buffer);
    EXPECT_EQ(ret, IPC_PARA_PROCESS_ERR_INVALID_VALUE);
}

TEST(SecStorageIpcStubSerialTest, AllocateSlotInputFromBufferNullptr)
{
    {
        auto ret = AllocateSlotInputFromBuffer(nullptr, nullptr, nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        SharedDataBuffer buffer = {};
        auto ret = AllocateSlotInputFromBuffer(&buffer, nullptr, nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        SharedDataBuffer buffer = {};
        StorageFileName name = {0};
        auto ret = AllocateSlotInputFromBuffer(&buffer, &name, nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        SharedDataBuffer buffer = {};
        StorageFileName name = {0};
        StorageSlotAttr attr;
        auto ret = AllocateSlotInputFromBuffer(&buffer, &name, &attr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
}

TEST(SecStorageIpcStubSerialTest, AllocateSlotInputFromBufferCaseSuccess)
{
    std::string inputStr = "39393030383830300000000000000000" // name = "99008800"
                           "02000000"                         // attr.algo = 2
                           "0A000000"                         // resetLevel = 0xa
                           "64000000"                         // attr.size = 0x64
                           "0B000000"                         // authOnRead = 0xb
                           "0C000000"                         // authOnWrite = 0xc
                           "0D000000"                         // authOnFree = 0xd
                           "08000000"                         // key size = 8
                           "0102030405060708";                // key data
    auto input = TestHelpers::HexStringToVector(inputStr);
    SharedDataBuffer buffer {
        .data = input.data(),
        .dataSize = static_cast<uint32_t>(input.size()),
        .dataMaxSize = static_cast<uint32_t>(input.size()),
    };
    StorageFileName name = {0};
    StorageSlotAttr attr = {ALGO_HKDF_SHA256, LEVEL_USER_WIPE, 0, 0, 0, 0};
    uint8_t keyData[128] = {0};
    StorageAuthKey key = {.keyData = keyData, .keySize = sizeof(keyData)};

    auto ret = AllocateSlotInputFromBuffer(&buffer, &name, &attr, &key);
    EXPECT_EQ(ret, SUCCESS);

    EXPECT_EQ(TestHelpers::VectorToHexString(name.handle, SEC_STORAGE_FILE_NAME_SIZE_MAX),
        "39393030383830300000000000000000");
    EXPECT_EQ(static_cast<uint32_t>(attr.algo), 2);
    EXPECT_EQ(static_cast<uint32_t>(attr.resetLevel), 0xa);
    EXPECT_EQ(static_cast<uint32_t>(attr.size), 0x64);
    EXPECT_EQ(static_cast<uint32_t>(attr.authOnRead), 0xb);
    EXPECT_EQ(static_cast<uint32_t>(attr.authOnWrite), 0xc);
    EXPECT_EQ(static_cast<uint32_t>(attr.authOnFree), 0xd);
    EXPECT_EQ(static_cast<uint32_t>(key.keySize), 8);
    EXPECT_EQ(TestHelpers::VectorToHexString(key.keyData, key.keySize), "0102030405060708");
}

TEST(SecStorageIpcStubSerialTest, AllocateSlotInputFromBufferCaseMsgSizeError)
{
    auto process = [](const std::string &inputStr) -> ResultCode {
        auto input = TestHelpers::HexStringToVector(inputStr);
        SharedDataBuffer buffer {
            .data = input.data(),
            .dataSize = static_cast<uint32_t>(input.size()),
            .dataMaxSize = static_cast<uint32_t>(input.size()),
        };
        StorageFileName name = {0};
        StorageSlotAttr attr = {ALGO_HKDF_SHA256, LEVEL_USER_WIPE, 0, 0, 0, 0};
        uint8_t keyData[128] = {0};
        StorageAuthKey key = {.keyData = keyData, .keySize = sizeof(keyData)};
        return AllocateSlotInputFromBuffer(&buffer, &name, &attr, &key);
    };

    {
        std::string inputStr = "3939303038383030"; // name size is not enough
        EXPECT_EQ(process(inputStr), IPC_PARA_PROCESS_ERR_INDEX_1);
    }

    {
        std::string inputStr = "39393030383830300000000000000000" // name = "99008800"
                               "1111111";                         // attr size is not enough
        EXPECT_EQ(process(inputStr), IPC_PARA_PROCESS_ERR_INDEX_2);
    }
    {
        std::string inputStr = "39393030383830300000000000000000" // name = "99008800"
                               "02000000"                         // attr.algo = 2
                               "0A000000"                         // resetLevel = 0xa
                               "64000000"                         // attr.size = 0x64
                               "0B000000"                         // authOnRead = 0xb
                               "0C000000"                         // authOnWrite = 0xc
                               "0D000000"                         // authOnFree = 0xd
                               "0800";                            // key size is not enough
        EXPECT_EQ(process(inputStr), IPC_PARA_PROCESS_ERR_INDEX_3);
    }
    {
        std::string inputStr = "39393030383830300000000000000000" // name = "99008800"
                               "02000000"                         // attr.algo = 2
                               "0A000000"                         // resetLevel = 0xa
                               "64000000"                         // attr.size = 0x64
                               "0B000000"                         // authOnRead = 0xb
                               "0C000000"                         // authOnWrite = 0xc
                               "0D000000"                         // authOnFree = 0xd
                               "08000000"                         // key size = 8
                               "010203040";                       // key data is not enough
        EXPECT_EQ(process(inputStr), IPC_PARA_PROCESS_ERR_INDEX_4);
    }
}

TEST(SecStorageIpcStubSerialTest, WriteSlotInputFromBufferNullptr)
{
    {
        auto ret = WriteSlotInputFromBuffer(nullptr, nullptr, nullptr, nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        SharedDataBuffer buffer = {};
        auto ret = WriteSlotInputFromBuffer(&buffer, nullptr, nullptr, nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        SharedDataBuffer buffer = {};
        StorageFileName name = {0};
        auto ret = WriteSlotInputFromBuffer(&buffer, &name, nullptr, nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        SharedDataBuffer buffer = {};
        StorageFileName name = {0};
        StorageAuthKey key = {};
        auto ret = WriteSlotInputFromBuffer(&buffer, &name, &key, nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        SharedDataBuffer buffer = {};
        StorageFileName name = {0};
        StorageAuthKey key = {};
        StorageDataArea area = {};
        auto ret = WriteSlotInputFromBuffer(&buffer, &name, &key, &area, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
}

TEST(SecStorageIpcStubSerialTest, WriteSlotInputFromBufferSuccess)
{
    std::string inputStr = "74657374000000000000000000000000" // name = "test"
                           "08000000"                         // key size = 8
                           "0102030405060708"                 // key data = {1,2,3,4,5,6,7,8}
                           "DDCC"                             // area.offset = 0xccdd
                           "FFEE"                             // area.length = 0xeeff
                           "0A000000"                         // data length = 10
                           "AABBCCDDEEFF11223344"; // {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x11, 0x22, 0x33, 0x44}

    auto input = TestHelpers::HexStringToVector(inputStr);
    SharedDataBuffer buffer {
        .data = input.data(),
        .dataSize = static_cast<uint32_t>(input.size()),
        .dataMaxSize = static_cast<uint32_t>(input.size()),
    };

    StorageFileName name = {0};

    uint8_t keyData[128] = {0};
    StorageAuthKey key = {.keyData = keyData, .keySize = sizeof(keyData)};

    StorageDataArea area = {0, 0};

    uint8_t bufferData[128] = {0};
    StorageDataBuffer storageData = {.bufferData = bufferData, .bufferSize = sizeof(bufferData)};

    auto ret = WriteSlotInputFromBuffer(&buffer, &name, &key, &area, &storageData);

    EXPECT_EQ(ret, SUCCESS);

    EXPECT_EQ(TestHelpers::VectorToHexString(name.handle, SEC_STORAGE_FILE_NAME_SIZE_MAX),
        "74657374000000000000000000000000");
    EXPECT_EQ(key.keySize, 8);
    EXPECT_EQ(TestHelpers::VectorToHexString(key.keyData, key.keySize), "0102030405060708");
    EXPECT_EQ(area.length, 0xeeff);
    EXPECT_EQ(area.offset, 0xccdd);
    EXPECT_EQ(TestHelpers::VectorToHexString(storageData.bufferData, storageData.bufferSize), "AABBCCDDEEFF11223344");
}

TEST(SecStorageIpcStubSerialTest, WriteSlotInputFromBufferErrorSize)
{
    auto process = [](const std::string &inputStr) -> ResultCode {
        auto input = TestHelpers::HexStringToVector(inputStr);
        SharedDataBuffer buffer {
            .data = input.data(),
            .dataSize = static_cast<uint32_t>(input.size()),
            .dataMaxSize = static_cast<uint32_t>(input.size()),
        };

        StorageFileName name = {0};

        uint8_t keyData[128] = {0};
        StorageAuthKey key = {.keyData = keyData, .keySize = sizeof(keyData)};
        StorageDataArea area = {0, 0};

        uint8_t bufferData[128] = {0};

        StorageDataBuffer storageData = {.bufferData = bufferData, .bufferSize = sizeof(bufferData)};

        return WriteSlotInputFromBuffer(&buffer, &name, &key, &area, &storageData);
    };
    {
        std::string inputStr = "746573740000000000"; // name size is not enough
        EXPECT_EQ(process(inputStr), IPC_PARA_PROCESS_ERR_INDEX_1);
    }
    {
        std::string inputStr = "74657374000000000000000000000000" // name = "test"
                               "08000000"                         // key size = 8
                               "0102030405060708"                 // key data = {1,2,3,4,5,6,7,8}
                               "DDCC"                             // area.offset = 0xccdd
                               "FFEE"                             // area.length = 0xeeff
                               "0A";                              // data.length is not enough
        EXPECT_EQ(process(inputStr), IPC_PARA_PROCESS_ERR_INDEX_2);
    }
    {
        std::string inputStr = "74657374000000000000000000000000" // name = "test"
                               "08000000"                         // key size = 8
                               "0102030405060708"                 // key data = {1,2,3,4,5,6,7,8}
                               "DDCC"                             // area.offset = 0xccdd
                               "FFEE"                             // area.length = 0xeeff
                               "0A000000"                         // data length = 10
                               "AABBCCDDEEFF11"; // {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x11, 0x22, 0x33, 0x44}
        EXPECT_EQ(process(inputStr), IPC_PARA_PROCESS_ERR_INDEX_3);
    }
}

TEST(SecStorageIpcStubSerialTest, ReadSlotInputFromBufferNullptr)
{
    {
        auto ret = ReadSlotInputFromBuffer(nullptr, nullptr, nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        SharedDataBuffer buffer = {};
        auto ret = ReadSlotInputFromBuffer(&buffer, nullptr, nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        SharedDataBuffer buffer = {};
        StorageFileName name = {0};
        auto ret = ReadSlotInputFromBuffer(&buffer, &name, nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        SharedDataBuffer buffer = {};
        StorageFileName name = {0};

        uint8_t keyData[128] = {0};
        StorageAuthKey key = {.keyData = keyData, .keySize = sizeof(keyData)};
        auto ret = ReadSlotInputFromBuffer(&buffer, &name, &key, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
}

TEST(SecStorageIpcStubSerialTest, ReadSlotInputFromBufferSuccess)
{
    std::string inputStr = "74657374696E67000000000000000000" // name = "testing"
                           "08000000"                         // key size = 8
                           "0102030405060708"                 // key data = {1,2,3,4,5,6,7,8}
                           "0100"                             // area.offset = 0x01
                           "0200";                            // area.length = 0x02
    auto input = TestHelpers::HexStringToVector(inputStr);

    SharedDataBuffer buffer {
        .data = input.data(),
        .dataSize = static_cast<uint32_t>(input.size()),
        .dataMaxSize = static_cast<uint32_t>(input.size()),
    };

    StorageFileName name = {0};

    uint8_t keyData[128] = {0};
    StorageAuthKey key = {.keyData = keyData, .keySize = sizeof(keyData)};

    StorageDataArea area = {0, 0};

    auto ret = ReadSlotInputFromBuffer(&buffer, &name, &key, &area);
    EXPECT_EQ(ret, SUCCESS);

    EXPECT_EQ(TestHelpers::VectorToHexString(name.handle, SEC_STORAGE_FILE_NAME_SIZE_MAX),
        "74657374696E67000000000000000000");

    EXPECT_EQ(key.keySize, 8);
    EXPECT_EQ(TestHelpers::VectorToHexString(key.keyData, key.keySize), "0102030405060708");

    EXPECT_EQ(area.offset, 1);
    EXPECT_EQ(area.length, 2);
}

TEST(SecStorageIpcStubSerialTest, ReadSlotInputFromBufferSizeIsNotRight)
{
    std::string inputStr = "74657374696E67000000000000000000"; // input length is not enough
    auto input = TestHelpers::HexStringToVector(inputStr);

    SharedDataBuffer buffer {
        .data = input.data(),
        .dataSize = static_cast<uint32_t>(input.size()),
        .dataMaxSize = static_cast<uint32_t>(input.size()),
    };

    StorageFileName name = {0};

    uint8_t keyData[128] = {0};
    StorageAuthKey key = {.keyData = keyData, .keySize = sizeof(keyData)};

    StorageDataArea area = {0, 0};

    auto ret = ReadSlotInputFromBuffer(&buffer, &name, &key, &area);
    EXPECT_EQ(ret, IPC_PARA_PROCESS_ERR_INVALID_VALUE);
}

TEST(SecStorageIpcStubSerialTest, ReadSlotOutputToBufferNullptr)
{
    {
        auto ret = ReadSlotOutputToBuffer(nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        StorageDataBuffer buffer = {};
        auto ret = ReadSlotOutputToBuffer(&buffer, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
}

TEST(SecStorageIpcStubSerialTest, ReadSlotOutputToBufferSuccess)
{
    uint8_t data[] = {1, 2, 3, 4, 5, 6, 7, 8};
    StorageDataBuffer buffer = {.bufferData = data, .bufferSize = sizeof(data)};

    uint8_t out[128] = {0};
    SharedDataBuffer dataBuffer = {.data = out, .dataSize = sizeof(out), .dataMaxSize = sizeof(out)};

    auto ret = ReadSlotOutputToBuffer(&buffer, &dataBuffer);
    EXPECT_EQ(ret, SUCCESS);
    EXPECT_EQ(dataBuffer.dataSize, sizeof(data));
    EXPECT_EQ(TestHelpers::VectorToHexString(dataBuffer.data, dataBuffer.dataSize), "0102030405060708");
}

TEST(SecStorageIpcStubSerialTest, ReadSlotOutputToBufferFailed)
{
    uint8_t data[] = {1, 2, 3, 4, 5, 6, 7, 8};
    StorageDataBuffer buffer = {.bufferData = data, .bufferSize = sizeof(data)};

    uint8_t out[4] = {0};
    SharedDataBuffer dataBuffer = {.data = out, .dataSize = sizeof(out), .dataMaxSize = sizeof(out)};

    auto ret = ReadSlotOutputToBuffer(&buffer, &dataBuffer);
    EXPECT_EQ(ret, MEM_COPY_ERR);
}

TEST(SecStorageIpcStubSerialTest, FreeSlotInputFromBufferNullptr)
{
    {
        auto ret = FreeSlotInputFromBuffer(nullptr, nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        SharedDataBuffer buffer = {};
        auto ret = FreeSlotInputFromBuffer(&buffer, nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        SharedDataBuffer buffer = {};
        StorageFileName name = {0};
        auto ret = FreeSlotInputFromBuffer(&buffer, &name, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
}

TEST(SecStorageIpcStubSerialTest, FreeSlotInputFromBufferSuccess)
{
    std::string inputStr = "74657374696E67000000000000000000" // name = "testing"
                           "08000000"                         // key size = 8
                           "0102030405060708";                // key data = {1,2,3,4,5,6,7,8}
    auto input = TestHelpers::HexStringToVector(inputStr);

    SharedDataBuffer buffer {
        .data = input.data(),
        .dataSize = static_cast<uint32_t>(input.size()),
        .dataMaxSize = static_cast<uint32_t>(input.size()),
    };

    StorageFileName name = {0};

    uint8_t data[128] = {0};
    StorageAuthKey key = {.keyData = data, .keySize = sizeof(data)};
    auto ret = FreeSlotInputFromBuffer(&buffer, &name, &key);

    EXPECT_EQ(ret, SUCCESS);

    EXPECT_EQ(TestHelpers::VectorToHexString(name.handle, SEC_STORAGE_FILE_NAME_SIZE_MAX),
        "74657374696E67000000000000000000");

    EXPECT_EQ(key.keySize, 8);
    EXPECT_EQ(TestHelpers::VectorToHexString(key.keyData, key.keySize), "0102030405060708");
}

TEST(SecStorageIpcStubSerialTest, FreeSlotInputFromBufferErrorInputSize)
{
    auto process = [](const std::string &inputStr) -> ResultCode {
        auto input = TestHelpers::HexStringToVector(inputStr);

        SharedDataBuffer buffer {
            .data = input.data(),
            .dataSize = static_cast<uint32_t>(input.size()),
            .dataMaxSize = static_cast<uint32_t>(input.size()),
        };

        StorageFileName name = {0};

        uint8_t data[128] = {0};
        StorageAuthKey key = {.keyData = data, .keySize = sizeof(data)};
        return FreeSlotInputFromBuffer(&buffer, &name, &key);
    };

    {
        std::string inputStr = "74657374696E670000"; // name length is not enough
        EXPECT_EQ(process(inputStr), IPC_PARA_PROCESS_ERR_INDEX_1);
    }
    {
        std::string inputStr = "74657374696E67000000000000000000" // name = "testing"
                               "0800";                            // key size is not enough

        EXPECT_EQ(process(inputStr), IPC_PARA_PROCESS_ERR_INDEX_2);
    }
    {
        std::string inputStr = "74657374696E67000000000000000000" // name = "testing"
                               "08000000"                         // key size = 8
                               "0102030";                         // key data is not enough

        EXPECT_EQ(process(inputStr), IPC_PARA_PROCESS_ERR_INDEX_3);
    }
}

TEST(SecStorageIpcStubSerialTest, GetSlotStatusInputFromBufferNullptr)
{
    {
        auto ret = GetSlotStatusInputFromBuffer(nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        SharedDataBuffer buffer = {};
        auto ret = GetSlotStatusInputFromBuffer(&buffer, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
}

TEST(SecStorageIpcStubSerialTest, GetSlotStatusInputFromBufferSuccess)
{
    std::string inputStr = "74657374696E67000000000000000000"; // name = "testing"
    auto input = TestHelpers::HexStringToVector(inputStr);

    SharedDataBuffer buffer {
        .data = input.data(),
        .dataSize = static_cast<uint32_t>(input.size()),
        .dataMaxSize = static_cast<uint32_t>(input.size()),
    };
    StorageFileName name = {0};
    auto ret = GetSlotStatusInputFromBuffer(&buffer, &name);
    EXPECT_EQ(ret, SUCCESS);

    EXPECT_EQ(TestHelpers::VectorToHexString(name.handle, SEC_STORAGE_FILE_NAME_SIZE_MAX),
        "74657374696E67000000000000000000");
}

TEST(SecStorageIpcStubSerialTest, GetSlotStatusInputFromBufferErrorLength)
{
    std::string inputStr = "74657374696E670000000000000000000000000000000"; // name size is not right
    auto input = TestHelpers::HexStringToVector(inputStr);

    SharedDataBuffer buffer {
        .data = input.data(),
        .dataSize = static_cast<uint32_t>(input.size()),
        .dataMaxSize = static_cast<uint32_t>(input.size()),
    };
    StorageFileName name = {0};
    auto ret = GetSlotStatusInputFromBuffer(&buffer, &name);
    EXPECT_EQ(ret, MEM_COPY_ERR);
}

TEST(SecStorageIpcStubSerialTest, GetSlotStatusOutputToBufferNullptr)
{
    {
        auto ret = GetSlotStatusOutputToBuffer(nullptr, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
    {
        StorageSlotStatus status = {};
        auto ret = GetSlotStatusOutputToBuffer(&status, nullptr);
        EXPECT_EQ(ret, INVALID_PARA_NULL_PTR);
    }
}

TEST(SecStorageIpcStubSerialTest, GetSlotStatusOutputToBufferSuccess)
{
    StorageSlotStatus status = {};

    std::vector<uint8_t> input(128);
    SharedDataBuffer buffer {
        .data = input.data(),
        .dataSize = static_cast<uint32_t>(input.size()),
        .dataMaxSize = static_cast<uint32_t>(input.size()),
    };

    auto ret = GetSlotStatusOutputToBuffer(&status, &buffer);
    EXPECT_EQ(ret, SUCCESS);

    EXPECT_EQ(buffer.dataSize, sizeof(StorageSlotStatus));
}

TEST(SecStorageIpcStubSerialTest, GetSlotStatusOutputToBufferError)
{
    StorageSlotStatus status = {};

    std::vector<uint8_t> input(4); // size is small
    SharedDataBuffer buffer {
        .data = input.data(),
        .dataSize = static_cast<uint32_t>(input.size()),
        .dataMaxSize = static_cast<uint32_t>(input.size()),
    };

    auto ret = GetSlotStatusOutputToBuffer(&status, &buffer);
    EXPECT_EQ(ret, MEM_COPY_ERR);
}

TEST(SecStorageIpcStubSerialTest, ParcelReadStorageIndicatorNullptr)
{
    {
        auto ret = ParcelReadStorageIndicator(nullptr, nullptr, nullptr, nullptr);
        EXPECT_FALSE(ret);
    }
    {
        Parcel parcel = CreateParcel(128);
        auto ret = ParcelReadStorageIndicator(&parcel, nullptr, nullptr, nullptr);
        EXPECT_FALSE(ret);
        DeleteParcel(&parcel);
    }
    {
        Parcel parcel = CreateParcel(128);
        StorageFileName file = {0};
        auto ret = ParcelReadStorageIndicator(&parcel, &file, nullptr, nullptr);
        EXPECT_FALSE(ret);
        DeleteParcel(&parcel);
    }
    {
        Parcel parcel = CreateParcel(128);
        StorageFileName file = {0};
        StorageAuthKey key = {nullptr, 0};
        auto ret = ParcelReadStorageIndicator(&parcel, &file, &key, nullptr);
        EXPECT_FALSE(ret);
        DeleteParcel(&parcel);
    }
}

TEST(SecStorageIpcStubSerialTest, ParcelReadStorageIndicatorSuccess)
{
    auto process = [](const std::string &inputStr) -> bool {
        auto input = TestHelpers::HexStringToVector(inputStr);

        Parcel parcel = CreateParcelWithData(input.data(), static_cast<uint8_t>(input.size()));

        StorageFileName file = {0};

        uint8_t keyData[128] = {0};
        StorageAuthKey key = {.keyData = keyData, .keySize = sizeof(keyData)};

        StorageDataArea area;
        auto ret = ParcelReadStorageIndicator(&parcel, &file, &key, &area);
        DeleteParcel(&parcel);
        return ret;
    };
    {
        std::string inputStr = "74657374696E"; // name size is not enough
        EXPECT_FALSE(process(inputStr));
    }
    {
        std::string inputStr = "74657374696E67000000000000000000" // name = "testing"
                               "080000";                          // key size is not enough
        EXPECT_FALSE(process(inputStr));
    }
    {
        std::string inputStr = "74657374696E67000000000000000000" // name = "testing"
                               "08000000"                         // key size = 8
                               "01020304050607";                  // key data is not enough
        EXPECT_FALSE(process(inputStr));
    }
    {
        std::string inputStr = "74657374696E67000000000000000000" // name = "testing"
                               "08000000"                         // key size = 8
                               "0102030405060708"                 // key data = {1,2,3,4,5,6,7,8}
                               "01";                              // area is not enough
        EXPECT_FALSE(process(inputStr));
    }
}

TEST(SecStorageIpcStubSerialTest, ParcelReadStorageIndicatorFailed)
{
    std::string inputStr = "74657374696E67000000000000000000" // name = "testing"
                           "08000000"                         // key size = 8
                           "0102030405060708"                 // key data = {1,2,3,4,5,6,7,8}
                           "0100"                             // area.offset = 0x01
                           "0200";                            // area.length = 0x02

    auto input = TestHelpers::HexStringToVector(inputStr);

    Parcel parcel = CreateParcelWithData(input.data(), static_cast<uint8_t>(input.size()));

    StorageFileName file = {0};

    uint8_t keyData[128] = {0};
    StorageAuthKey key = {.keyData = keyData, .keySize = sizeof(keyData)};

    StorageDataArea area;
    auto ret = ParcelReadStorageIndicator(&parcel, &file, &key, &area);
    EXPECT_TRUE(ret);

    EXPECT_EQ(TestHelpers::VectorToHexString(file.handle, SEC_STORAGE_FILE_NAME_SIZE_MAX),
        "74657374696E67000000000000000000");

    EXPECT_EQ(key.keySize, 8);
    EXPECT_EQ(TestHelpers::VectorToHexString(key.keyData, key.keySize), "0102030405060708");

    EXPECT_EQ(area.offset, 0x1);
    EXPECT_EQ(area.length, 0x2);
    DeleteParcel(&parcel);
}

TEST(SecStorageIpcStubSerialTest, ParcelToSharedDataBufferNullptr)
{
    {
        auto ret = ParcelToSharedDataBuffer(nullptr, nullptr);
        EXPECT_FALSE(ret);
    }
    {
        Parcel parcel = CreateParcel(128);
        auto ret = ParcelToSharedDataBuffer(&parcel, nullptr);
        EXPECT_FALSE(ret);

        DeleteParcel(&parcel);
    }
}
} // namespace UnitTest
} // namespace SeBaseServices
} // namespace OHOS